/*
 *
 * 名称：方案窗口
 * 功能：奇门遁甲断局方案配置窗口
 * 作者：清河张
 * 时间：2025.05.11
 *
 */

#include "fanganwin.h"
#include "ui_fanganwin.h"
#include "base/bazi.h"
#include "base/gua8.h"

#include <QComboBox>
#include <QKeyEvent>
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QJsonArray>
#include <QMessageBox>

using namespace QMDJ;

FANGANWIN::FANGANWIN(QWidget *parent, FANGAN& fangan)
    : QDialog(parent)
    , ui(new Ui_FANGANWIN)
    , _fangan(fangan)
{
    ui->setupUi(this);

    initxg();

    initgj();

    initys();

    initgx();
}

FANGANWIN::~FANGANWIN()
{
    delete ui;
}

void FANGANWIN::load(qint64 id)
{
    _fangan.load(id);
    _jsonObj = _fangan.jsonObj();

    if(_jsonObj[YSFANGAN].isNull() )
        _jsonObj[YSFANGAN] = "";

    ui->fanganLineEdit->setText(_jsonObj[YSFANGAN].toString());

    loadys();
    loadgx();
    loadgj();
    loadxg();
}

void FANGANWIN::store()
{
    store_input(ui->curCellLineEdit->text());
    storeys();
    storegx();
    storegj();
    storexg();
    _jsonObj[YSFANGAN] = ui->fanganLineEdit->text();
    _fangan.store(_jsonObj);
}

QString FANGANWIN::name() const
{
    return _jsonObj[YSFANGAN].toString();
}

void FANGANWIN::on_ranyePushButton_clicked()
{
    store();
    done(0);
    this->hide();
}


void FANGANWIN::on_quyePushButton_clicked()
{
    done(-1);
    this->hide();
}


void FANGANWIN::initgj()
{
    ui->gjTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->gjTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}

void FANGANWIN::initxg()
{
    ui->xgTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->xgTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    for(int i = 0; i < 10; ++i)
    {
        GAN10 g = i;
        ui->tianpanComboBox->addItem( g.name(), g.id());
        ui->dipanComboBox->addItem( g.name(), g.id());
    }
}

void FANGANWIN::initgx()
{
    ui->gxTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->gxTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->gxTableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeMode::Fixed);
    ui->gxTableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Fixed);
    ui->gxTableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeMode::Fixed);
    ui->gxTableWidget->setColumnWidth(0, 120);
    ui->gxTableWidget->setColumnWidth(1, 60);
    ui->gxTableWidget->setColumnWidth(2, 120);
}

void FANGANWIN::initys()
{
    ui->ysTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}

void FANGANWIN::loadgj()
{
    QJsonObject&& jsonGJ = _jsonObj[YSGEJU].toObject();

    for(ushort i = 1; i < 10; ++i)
    {
        QJsonObject&& jsonDP = jsonGJ[QString::number(i)].toObject();
        for(ushort j = 1; j < 10; ++j)
        {
            ui->gjTableWidget->item(i-1, j-1)->setText(
                jsonDP[QString::number(j)].toString());
        }
    }
}

void FANGANWIN::loadxg()
{
    QJsonObject&& jsonXG = _jsonObj[YSXINGGONG].toObject();

    for(ushort i = 0; i < 9; ++i)
    {
        QJsonObject&& jsonJX = jsonXG[QString::number(i)].toObject();
        for(ushort j = 0; j < 9; ++j)
        {
            ui->xgTableWidget->item(i, j)->setText(
                jsonJX[QString::number(j)].toString());
        }
    }
}

void FANGANWIN::loadgx()
{
    QJsonArray&& jsonGX = _jsonObj[YSGUANXI].toArray();
    ui->gxTableWidget->setRowCount(0);

    for(int row = 0; row < jsonGX.count(); ++row)
    {
        QJsonObject&& gx= jsonGX[row].toObject();
        appendgx(gx[YSPAIFU1].toInt(), gx[YSGUANXIS].toInt(), gx[YSPAIFU2].toInt(), gx[YSGXXY].toString());
    }
}

void FANGANWIN::loadys()
{
    QJsonArray&& jsonYS = _jsonObj[YSFIELD].toArray();
    ui->ysTableWidget->setRowCount(0);

    for(int row = 0; row < jsonYS.count(); ++row)
    {
        QJsonObject&& ys = jsonYS[row].toObject();

        appendys(ys[YSPAIFU].toInt(),
                 ys[YSMING].toString(),
                 ys[YSBULUO].toInt(),
                 ys[YSBIANHAO].toInt(),
                 ys[YSXINGJI].toString(),
                 ys[YSKONGWANG].toString(),
                 ys[YSMENPO].toString(),
                 ys[YSRUMU].toString(),
                 ys[XIANGYI].toString());
    }
    ui->ysTableWidget->sortItems(0);
}

void FANGANWIN::storegj()
{
    QJsonObject jsonGJ;

    for(ushort i = 1; i < 10; ++i)
    {
        QJsonObject jsonTP;
        for(ushort j = 1; j < 10; ++j)
        {
            jsonTP[QString::number(j)] = ui->gjTableWidget->item(i-1, j-1)->text();
        }
        jsonGJ[QString::number(i)] = jsonTP;
    }

    _jsonObj[YSGEJU] = jsonGJ;
}

void FANGANWIN::storexg()
{
    QJsonObject jsonXG;

    for(ushort i = 0; i < 9; ++i)
    {
        QJsonObject jsonJX;
        for(ushort j = 0; j < 9; ++j)
        {
            jsonJX[QString::number(j)] = ui->xgTableWidget->item(i, j)->text();
        }
        jsonXG[QString::number(i)] = jsonJX;
    }

    _jsonObj[YSXINGGONG] = jsonXG;
}

void FANGANWIN::storegx()
{
    QJsonArray jsonGX;
    int column;
    for(int row = 0; row < ui->gxTableWidget->rowCount(); ++row)
    {
        QJsonObject gx;
        column = 0;

        QComboBox* pf1 = static_cast<QComboBox*>(ui->gxTableWidget->cellWidget(row,column++));
        QComboBox* gxs = static_cast<QComboBox*>(ui->gxTableWidget->cellWidget(row,column++));
        QComboBox* pf2 = static_cast<QComboBox*>(ui->gxTableWidget->cellWidget(row,column++));

        gx[YSPAIFU1] = pf1->currentData().toInt();
        gx[YSGUANXIS] = gxs->currentData().toInt();
        gx[YSPAIFU2] = pf2->currentData().toInt();
        gx[YSGXXY] = ui->gxTableWidget->item(row, column++)->text();
        jsonGX.push_back(gx);
    }

    _jsonObj[YSGUANXI] = jsonGX;
}

void FANGANWIN::storeys()
{
    int column;
    char buf[128];
    int pf;
    QJsonArray jsonYS;

    for(int i = 0; i < ui->ysTableWidget->rowCount(); ++i)
    {
        column = 0;
        QJsonObject ys;
        pf = ui->ysTableWidget->item(i, column++)->text().toInt();
        for(int i = 0; i < jsonYS.count(); ++i)
        {
            QJsonObject ys0 = jsonYS[i].toObject();
            if(ys0[YSPAIFU].toInteger() == pf)
            {
                std::snprintf(buf, sizeof(buf),
                              "牌符号 \"%d\" 重也", pf);
                QMessageBox::information(this, "谬也", buf);
            }
        }

        ys[YSPAIFU] = pf;
        ys[YSMING] = ui->ysTableWidget->item(i, column++)->text();

        QComboBox* blCbx = static_cast<QComboBox*>(ui->ysTableWidget->cellWidget(i,column++));
        QComboBox* bzCbx = static_cast<QComboBox*>(ui->ysTableWidget->cellWidget(i,column++));

        ys[YSBULUO] = blCbx->currentData().toInt();
        ys[YSBIANHAO] = bzCbx->currentData().toInt();
        ys[YSXINGJI] = ui->ysTableWidget->item(i, column++)->text();
        ys[YSKONGWANG] = ui->ysTableWidget->item(i, column++)->text();
        ys[YSMENPO] = ui->ysTableWidget->item(i, column++)->text();
        ys[YSRUMU] = ui->ysTableWidget->item(i, column++)->text();
        ys[XIANGYI] = ui->ysTableWidget->item(i, column++)->text();
        jsonYS.push_back(ys);
    }

    _jsonObj[YSFIELD] = jsonYS;
}

void FANGANWIN::appendys(int pf, const QString& mh, int bl, int bz,
                       const QString& x, const QString& k, const QString& p,
                       const QString& m, const QString& xy)
{
    int lastrow, column = 0;

    QComboBox* blCbx = new QComboBox();
    QComboBox* bzCbx = new QComboBox();
    blCbx->addItem("特殊", EQM_YS_TESHU);
    blCbx->addItem("九星", EQM_YS_XING9);
    blCbx->addItem("八门", EQM_YS_MMEN8);
    blCbx->addItem("八神", EQM_YS_SHEN8);
    blCbx->addItem("天盘", EQM_YS_TPGAN);
    blCbx->addItem("地盘", EQM_YS_DPGAN);
    blCbx->addItem("九宫", EQM_YS_GONG9);
    blCbx->addItem("先卦", EQM_YS_XTGUA);
    blCbx->addItem("后卦", EQM_YS_HTGUA);
    blCbx->addItem("地支", EQM_YS_DIZHI);
    blCbx->addItem("命时", EQM_YS_MINSH);

    blCbx->setCurrentIndex(-1);

    lastrow = ui->ysTableWidget->rowCount();
    ui->ysTableWidget->insertRow(lastrow);

    for(int i = 0; i < ui->ysTableWidget->columnCount(); ++i)
        ui->ysTableWidget->setItem(lastrow, i, new QTableWidgetItem(""));

    if(pf < 0)
    {
        if(lastrow > 0)
            pf = ui->ysTableWidget->item(lastrow - 1, 0)->text().toInt();
        else
            pf = 0;
        pf ++;
    }

    ui->ysTableWidget->item(lastrow, column++)->setText(QString::number(pf));
    ui->ysTableWidget->item(lastrow, column++)->setText(mh);
    ui->ysTableWidget->setCellWidget(lastrow, column++, blCbx);
    ui->ysTableWidget->setCellWidget(lastrow, column++, bzCbx);

    ui->ysTableWidget->item(lastrow, column++)->setText(x);
    ui->ysTableWidget->item(lastrow, column++)->setText(k);
    ui->ysTableWidget->item(lastrow, column++)->setText(p);
    ui->ysTableWidget->item(lastrow, column++)->setText(m);
    ui->ysTableWidget->item(lastrow, column++)->setText(xy);

    connect(blCbx, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, [this, blCbx, lastrow, bz]()
            {
                QComboBox* bzCbx = static_cast<QComboBox*>(
                ui->ysTableWidget->cellWidget(lastrow,3));
                    bzCbx->clear();

                switch(blCbx->currentData().toInt())
                {
                case EQM_YS_TESHU:
                    bzCbx->addItem("值符", EQM_YS_ZHFU);
                    bzCbx->addItem("值使", EQM_YS_ZHSH);
                    bzCbx->addItem("年干", EQM_YS_NGAN);
                    bzCbx->addItem("月干", EQM_YS_YGAN);
                    bzCbx->addItem("日干", EQM_YS_RGAN);
                    bzCbx->addItem("时干", EQM_YS_SGAN);
                    bzCbx->addItem("年支", EQM_YS_NZHI);
                    bzCbx->addItem("月支", EQM_YS_YZHI);
                    bzCbx->addItem("日支", EQM_YS_RZHI);
                    bzCbx->addItem("时支", EQM_YS_NZHI);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_XING9:
                    for(int i = 0; i < 9; ++i)
                        bzCbx->addItem(XING9(i).name(), i);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_MMEN8:
                    for(int i = 0; i < 8; ++i)
                        bzCbx->addItem(MEN8(i).name(), i);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_SHEN8:
                    for(int i = 0; i < 8; ++i)
                        bzCbx->addItem(SHEN8(i).name(), i);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_TPGAN:
                case EQM_YS_DPGAN:
                    for(int i = 1; i< 10; ++i)
                        bzCbx->addItem(GAN10(i).name(), i);
                    bzCbx->setCurrentIndex(bz - 1);
                    break;
                case EQM_YS_GONG9:
                    for(int i = 0; i < 9; ++i)
                        bzCbx->addItem(_fangan.gong9().gong(i)->name(), i);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_XTGUA:
                case EQM_YS_HTGUA:
                    for(int i = 1; i< 9; ++i)
                        bzCbx->addItem(GUA8(i).name(), i);
                    bzCbx->setCurrentIndex(bz - 1);
                    break;
                case EQM_YS_DIZHI:
                    for(int i = 0; i< 12; ++i)
                        bzCbx->addItem(ZHI12(i).name(), i);
                    bzCbx->setCurrentIndex(bz);
                    break;
                case EQM_YS_MINSH:
                    bzCbx->addItem("年干", EQM_YS_NGAN);
                    bzCbx->addItem("月干", EQM_YS_YGAN);
                    bzCbx->addItem("日干", EQM_YS_RGAN);
                    bzCbx->addItem("时干", EQM_YS_SGAN);
                    bzCbx->addItem("年支", EQM_YS_NZHI);
                    bzCbx->addItem("月支", EQM_YS_YZHI);
                    bzCbx->addItem("日支", EQM_YS_RZHI);
                    bzCbx->addItem("时支", EQM_YS_NZHI);
                    bzCbx->setCurrentIndex(bz - 2);
                default:
                    break;
                    }
                ui->ysTableWidget->setCellWidget(lastrow, 3, bzCbx);
            }
            );

    blCbx->setCurrentIndex(bl);
}

void FANGANWIN::appendgx(int pf1, int gxs, int pf2, const QString& xinagyi)
{
    int lastrow, column = 0, pf;

    QComboBox *ys1 = new QComboBox();
    QComboBox *gx = new QComboBox();
    QComboBox *ys2 = new QComboBox();

    ys1->setCurrentIndex(-1);
    ys2->setCurrentIndex(-1);

    for (int i =0; i < 5; ++i)
        gx->addItem(WUXING5::SHENGKE(i).name(), i);
    gx->addItem("逢", 5);
    gx->setCurrentIndex(gxs);

    for(int i = 0; i < ui->ysTableWidget->rowCount(); ++i)
    {
        pf = ui->ysTableWidget->item(i, 0)->text().toInt();
        const QString& ysmin = ui->ysTableWidget->item(i, 1)->text();
        ys1->addItem(ysmin, pf);
        ys2->addItem(ysmin, pf);

        if(pf1 == pf) ys1->setCurrentIndex(i);
        if(pf2 == pf) ys2->setCurrentIndex(i);
    }

    lastrow = ui->gxTableWidget->rowCount();
    ui->gxTableWidget->insertRow(lastrow);

    ui->gxTableWidget->setCellWidget(lastrow, column++, ys1);
    ui->gxTableWidget->setCellWidget(lastrow, column++, gx);
    ui->gxTableWidget->setCellWidget(lastrow, column++, ys2);

    ui->gxTableWidget->setItem(lastrow, column++, new QTableWidgetItem(xinagyi));

}

void FANGANWIN::clone_new_row(QTableWidget* tv, int offset)
{
    int row, nextrow;
    row = tv->currentRow();
    nextrow = tv->rowCount() - 1;
    if(nextrow < tv->rowCount())
    {
        if(row < 0) row = 0;

        for ( int col = offset; col < tv->columnCount(); ++col)
            tv->setItem(nextrow, col, tv->item(row, col)->clone());
    }
}

void FANGANWIN::clone_next_row(QTableWidget * tv, int offset)
{
    int row, nextrow;
    row = tv->currentRow();

    if(row < 0) return;

    nextrow = row + 1;
    if(nextrow < tv->rowCount())
    {
        for ( int col = offset; col < tv->columnCount(); ++col)
            tv->setItem(nextrow, col, tv->item(row, col)->clone());
    }
}

void FANGANWIN::on_buzhiPushButton_clicked()
{
    switch (ui->xyTabWidget->currentIndex()) {
    case 0:
        appendys(-1);
        break;
    case 1:
        appendgx(-1, -1, -1);
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
    }
}


void FANGANWIN::on_xiezhiPushButton_clicked()
{
    switch (ui->xyTabWidget->currentIndex()) {
    case 0:
        ui->ysTableWidget->removeRow(ui->ysTableWidget->currentRow());
        break;
    case 1:
        ui->gxTableWidget->removeRow(ui->gxTableWidget->currentRow());
        break;
    case 2:
        ui->gjTableWidget->currentItem()->setText("");
        break;
    case 3:
        ui->xgTableWidget->currentItem()->setText("");
        break;
    default:
        break;
    }
}


void FANGANWIN::on_xiaozhiPushButton_clicked()
{
    switch (ui->xyTabWidget->currentIndex()) {
    case 0:
        appendys(-1);
        clone_new_row(ui->ysTableWidget, 1);
        break;
    case 1:
        appendgx(-1,-1,-1);
        clone_new_row(ui->gxTableWidget, 2);
        break;
    case 2:
        clone_next_row(ui->gjTableWidget, 0);
        break;
    case 3:
        clone_next_row(ui->xgTableWidget, 0);
        break;
    default:
        break;
    }
}


void FANGANWIN::on_xuzhiPushButton_clicked()
{
    switch (ui->xyTabWidget->currentIndex()) {
    case 0:
        ui->ysTableWidget->setRowCount(0);
        break;
    case 1:
        ui->gxTableWidget->setRowCount(0);
        break;
    case 2:
        for(int i = 0; i < ui->gjTableWidget->rowCount(); ++i)
            for(int j = 0; j < ui->gjTableWidget->columnCount(); ++j)
                ui->gjTableWidget->item(i,j)->setText("");
        break;
    case 3:
        for(int i = 0; i < ui->xgTableWidget->rowCount(); ++i)
            for(int j = 0; j < ui->xgTableWidget->columnCount(); ++j)
                ui->xgTableWidget->item(i,j)->setText("");
        break;
    default:
        break;
    }
}


void FANGANWIN::on_ysTableWidget_cellChanged(int row, int column)
{
    if(row < 0 || column < 0) return ;
    ui->curCellLineEdit->setText(ui->ysTableWidget->item(row,column)->text());
}


void FANGANWIN::on_gxTableWidget_cellChanged(int row, int column)
{
    if(row < 0 || column < 0) return ;
    ui->curCellLineEdit->setText(ui->gxTableWidget->item(row,column)->text());
}


void FANGANWIN::on_gjTableWidget_cellChanged(int row, int column)
{
    if(row < 0 || column < 0) return ;
    ui->curCellLineEdit->setText(ui->gjTableWidget->item(row,column)->text());
}


void FANGANWIN::on_xgTableWidget_cellChanged(int row, int column)
{
    if(row < 0 || column < 0) return ;
    ui->curCellLineEdit->setText(ui->xgTableWidget->item(row,column)->text());
}


void FANGANWIN::store_input(const QString& input)
{
    QTableWidgetItem * item;
    switch (ui->xyTabWidget->currentIndex()) {
    case 0:
        item = ui->ysTableWidget->currentItem();
        break;
    case 1:
        item = ui->gxTableWidget->currentItem();
        break;
    case 2:
        item = ui->gjTableWidget->currentItem();
        break;
    case 3:
        item = ui->xgTableWidget->currentItem();
        break;
    default:
        item = nullptr;
        break;
    }
    if(item) item->setText(input);
}


void FANGANWIN::keyPressEvent(QKeyEvent *event)
{
    int k = event->key();
    switch(k)
    {
    case Qt::Key_Return:
    case Qt::Key_Enter:
        store_input(ui->curCellLineEdit->text());
        break;
    }
}


void FANGANWIN::on_gjTableWidget_cellClicked(int row, int column)
{
    ui->curCellLineEdit->setText(ui->gjTableWidget->item(row,column)->text());
}


void FANGANWIN::on_ysTableWidget_cellClicked(int row, int column)
{
    ui->curCellLineEdit->setText(ui->ysTableWidget->item(row,column)->text());
}


void FANGANWIN::on_gxTableWidget_cellClicked(int row, int column)
{
    ui->curCellLineEdit->setText(ui->gxTableWidget->item(row,column)->text());
}


void FANGANWIN::on_xgTableWidget_cellClicked(int row, int column)
{
    ui->curCellLineEdit->setText(ui->xgTableWidget->item(row,column)->text());
}


void FANGANWIN::on_curCellLineEdit_textEdited(const QString &arg1)
{
    store_input(arg1);
}


void FANGANWIN::on_chakeyingToolButton_clicked()
{
    ui->keyingbiaoLineEdit->setText(
        GAN10::gky(
            ui->tianpanComboBox->currentData().toInt(),
            ui->dipanComboBox->currentData().toInt()));
}

